package com.yang.service.impl;


import com.yang.common.Meta;
import com.yang.common.MetaTotal;
import com.yang.common.Result;
import com.yang.service.SearchService;
import org.apache.commons.beanutils.BeanUtils;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SearchServiceImpl implements SearchService {
    private final String resultIndex = "hanchuan001";

    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;


    /**
     * 根据msg关键字进行搜索，并实现分页查询和高亮显示
     *
     * @param msg
     * @param pageNo
     * @param pageSize
     * @return
     * @throws IOException
     */
//    @Override
//    public MetaTotal searchAllHighLight(String msg, int pageNo, int pageSize) throws IOException {
//        if(pageNo <= 1){
//            pageNo = 1;
//        }
//        SearchRequest request = new SearchRequest(resultIndex);
////      进行搜索
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        sourceBuilder.query(QueryBuilders.matchQuery("message", msg));
////        sourceBuilder.size(2000);
//
////        分页
//        sourceBuilder.from(pageNo);
//        sourceBuilder.size(pageSize);
//
//
////        进行高亮设置
//        HighlightBuilder highlightBuilder = new HighlightBuilder();
//        highlightBuilder.field("message");
//        highlightBuilder.preTags("<span style='color:red'>");
//        highlightBuilder.postTags("</span>");
//        sourceBuilder.highlighter(highlightBuilder);
//
////        加入到request中
//        request.source(sourceBuilder);
//
//        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//        List<Meta> list = new ArrayList<>();
//        for (SearchHit hit : response.getHits().getHits()) {
//            //----进行高亮字段的替换
//            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
//            HighlightField message = highlightFields.get("message");
//
//
//            Map<String,Object> sourceAsMap = hit.getSourceAsMap();
//            if (message!=null){
//                Text[] fragments = message.fragments();
//                String n_mess = "";
//                for (Text text : fragments) {
//                    n_mess += text;
//                }
//                sourceAsMap.put("message",n_mess);
//            }
//            //----结束----
//
//            Meta meta = new Meta();
//            try {
//                BeanUtils.populate(meta,hit.getSourceAsMap());
//            } catch (IllegalAccessException e) {
//                throw new RuntimeException(e);
//            } catch (InvocationTargetException e) {
//                throw new RuntimeException(e);
//            }
//            list.add(meta);
//        }
//        MetaTotal metas = new MetaTotal();
//        metas.setList(list);
//        metas.setTotal(response.getHits().getTotalHits().value);
//        System.out.println(metas.getTotal()+"总记录数");
//        return metas;
//    }
    /**
     * 根据msg关键字进行搜索，并实现分页查询和高亮显示
     *
     * @param msg
     * @param pageNo
     * @param pageSize
     * @return
     * @throws IOException
     */
    @Override
    public MetaTotal searchAllHighLight(String msg, int pageNo, int pageSize) throws IOException {
        if (pageNo <= 1) {
            pageNo = 1;
        }
        SearchRequest request = new SearchRequest(resultIndex);
//      进行搜索
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("message", msg))
                        .should(QueryBuilders.matchQuery("title", msg));

//        sourceBuilder.size(2000);

//        分页
        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);


//        进行高亮设置
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        HighlightBuilder.Field field = new HighlightBuilder.Field("message")
                .preTags("<span style='color:red'>")
                .postTags("</span>");
        HighlightBuilder.Field field1 = new HighlightBuilder.Field("title")
                .preTags("<span style='color:red'>")
                .postTags("</span>");
        highlightBuilder.field(field).field(field1);

        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.highlighter(highlightBuilder);

//        加入到request中
        request.source(sourceBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        List<Meta> list = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            //----进行高亮字段的替换
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField message = highlightFields.get("message");
            HighlightField title = highlightFields.get("title");

//          未高亮之前的结果
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//            1.找到message中出现关键字的地方进行高亮替换
            if (message != null) {
                Text[] fragments = message.fragments();
                String n_mess = "";
                for (Text text : fragments) {
                    n_mess += text;
                }
                sourceAsMap.put("message", n_mess);
            }
//            2.找到title中出现关键字的地方进行高亮替换
            if (title != null) {
                Text[] fragments = title.fragments();
                String n_title = "";
                for (Text text : fragments) {
                    n_title += text;
                }
                sourceAsMap.put("title", n_title);
            }
            //----结束----

            Meta meta = new Meta();
            try {
                BeanUtils.populate(meta, hit.getSourceAsMap());
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            list.add(meta);
        }
        MetaTotal metas = new MetaTotal();
        metas.setList(list);
        metas.setTotal(response.getHits().getTotalHits().value);
        System.out.println(metas.getTotal() + "总记录数");
        return metas;
    }
}
